using System;
using Rougamo;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
using Rougamo.Context;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Services
{
    /// <summary>
    /// 日志操作特性
    /// 基于AOP（面向切面编程）的日志记录特性，自动记录方法的进入、退出和异常信息
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
    public class LogOperationAttribute : MoAttribute
    {
        /// <summary>
        /// 方法入口拦截
        /// 在方法执行前记录方法名称和参数信息
        /// </summary>
        /// <param name="context">方法上下文信息</param>
        public override void OnEntry(MethodContext context)
        {
            var logger = GetLogger(context.Target);
            var traceId = Activity.Current?.TraceId.ToString();
            logger?.LogInformation($"[AOP-Entry] TraceId:{traceId} {context.Method.Name} 入参: {string.Join(",", context.Arguments)}");
        }

        /// <summary>
        /// 异常拦截
        /// 在方法执行过程中出现异常时记录异常信息
        /// </summary>
        /// <param name="context">方法上下文信息，包含异常详情</param>
        public override void OnException(MethodContext context)
        {
            var logger = GetLogger(context.Target);
            var traceId = Activity.Current?.TraceId.ToString();
            logger?.LogError(context.Exception, $"[AOP-Exception] TraceId:{traceId} {context.Method.Name} 异常: {context.Exception?.Message ?? "Unknown error"}");
        }

        /// <summary>
        /// 方法退出拦截
        /// 在方法执行完成后记录返回值信息
        /// </summary>
        /// <param name="context">方法上下文信息，包含返回值</param>
        public override void OnExit(MethodContext context)
        {
            var logger = GetLogger(context.Target);
            var traceId = Activity.Current?.TraceId.ToString();
            logger?.LogInformation($"[AOP-Exit] TraceId:{traceId} {context.Method.Name} 返回: {context.ReturnValue}");
        }

        /// <summary>
        /// 获取日志记录器
        /// 通过反射从目标对象中获取Logger属性或字段
        /// </summary>
        /// <param name="instance">目标对象实例</param>
        /// <returns>日志记录器实例，如果未找到则返回null</returns>
        private ILogger? GetLogger(object? instance)
        {
            // 可根据实际项目注入方式优化
            var loggerProp = instance?.GetType().GetProperty("Logger") ?? instance?.GetType().GetProperty("_logger");
            return loggerProp?.GetValue(instance) as ILogger;
        }
    }
}
